#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kprobes.h>
#include <linux/blkdev.h>

static struct kprobe kp;

static int kp_callback(struct kprobe *p, struct pt_regs *regs)
{
    struct request_queue *req;
    struct gendisk *disk;
    const char *disk_name;
    
    printk(KERN_INFO "kprobe:1");

    // 获取blk_mq_submit_bio的第一个参数，即请求队列
    req = (struct request_queue *)regs->di;

    printk(KERN_INFO "kprobe:2");
    if (!req)
        return 0;

    // 尝试获取请求队列关联的设备
    disk = req->disk;
    if (!disk)
        return 0;

    printk(KERN_INFO "kprobe:3");
    // 获取设备名称
    disk_name = disk->disk_name;

    // 检查设备名称是否为"sda"
    if (strcmp(disk_name, "sda") == 0) {
        printk(KERN_INFO "kprobe: blk_mq_submit_bio from /dev/sda, stopping execution\n");
        // 这里我们返回-1来表示我们需要退出当前函数
        return -1;
    }

    printk(KERN_INFO "kprobe: blk_mq_submit_bio from non-sda, continuing execution\n");
    return 0; // 继续执行
}

static int __init kprobe_init(void)
{
    kp.symbol_name = "blk_mq_submit_bio";
    kp.pre_handler = kp_callback;
    kp.post_handler = NULL;
    return register_kprobe(&kp);
}

static void __exit kprobe_exit(void)
{
    unregister_kprobe(&kp);
}

module_init(kprobe_init);
module_exit(kprobe_exit);
MODULE_LICENSE("GPL");
